from django.shortcuts import render
from rest_framework.decorators import action
from rest_framework.views import APIView
from rest_framework_jwt.views import ObtainJSONWebToken

from .models import User
from rest_framework.response import Response
from rest_framework.generics import RetrieveAPIView,UpdateAPIView
from rest_framework.permissions import IsAuthenticated
from .serializers import UserDetailSerializer,UserEmailSerializer
from rest_framework import status
from rest_framework.viewsets import GenericViewSet
from .serializers import AddressSerializer,AddressTitleSerializer
from rest_framework.mixins import ListModelMixin,UpdateModelMixin,DestroyModelMixin
from .models import Address
from rest_framework.generics import CreateAPIView,ListAPIView
from .serializers import UserBrowserHistorySerializer
from goods.models import SKU
from django_redis import get_redis_connection
from carts.utils import merge_cookie_redis_cart
"""
判断用户名是否存在
1, 前端携带用户名
2, 根据用户名,查询用户的数量,如果大于0,证明用户已经存在

APIView:        所有校验工作,数据转换工作都是自己做
GenericAPIView  提供序列化器, 只需要在get,post方法中编写逻辑
ListAPIView     连get等方法都不用写
"""
class UsernameCount(APIView):

    def get(self,request,username):
        #1,根据用户名在数据库查询用户数量
        count = User.objects.filter(username=username).count()

        #2,拼接数据返回响应
        return Response({
            "username":username,
            "count":count
        })

"""
判断用户手机号,在数据库是否存在;
1, 前端携带手机号过来
2, 根据手机号,在数据库查询,如果大于0次,则存在
"""
class MobileCount(APIView):

    def get(self,request,mobile):
        #1,根据用户名在数据库查询用户数量
        count = User.objects.filter(mobile=mobile).count()

        #2,拼接数据返回响应
        return Response({
            "mobile":mobile,
            "count":count
        })


"""
注册用户
1,前端携带,用户名,两次密码,手机号,短信验证码,协议
2,获取数据,校验数据(序列化器)
3,数据入库
4,返回响应(用户名,编号)

类视图选取:
1, APIView          什么都是自己写(校验,转换,逻辑)
2, GenericAPIView   提供序列化器 + 自己的逻辑
3, 三级视图           连post请求都不用写
"""
from rest_framework.generics import GenericAPIView,CreateAPIView
from .serializers import RegisterUserSerializer
from rest_framework.mixins import CreateModelMixin,UpdateModelMixin
class RegisterUserView(CreateAPIView):

    serializer_class = RegisterUserSerializer

    # def post(self,request):
        # #1,获取参数
        # dict_data = request.data
        #
        # #2,校验参数(序列化器)
        # serializer = self.get_serializer(data=dict_data)
        # serializer.is_valid(raise_exception=True) #一旦serializer处理完成之后,serializer.validated_data
        # # print(serializer.validate_data) #方法的返回值给我们
        #
        # #3,数据入库
        # user = serializer.save()
        #
        # #4,返回响应
        # serializer2 = self.get_serializer(instance=user)
        # return Response(serializer2.data) #序列化
        # return self.create(request)

"""
获取用户信息
请求路径: /users/infos
请求方式: GET,登陆认证
请求参数: 无
返回值: id, username,mobile,email,email_active
"""
class UserDetailView(RetrieveAPIView):

    #用户需要经过认证的
    permission_classes = [IsAuthenticated]

    serializer_class = UserDetailSerializer

    #使用该数据集,需要提供用户编号(pk)
    # queryset = User.objects.all()

    #重写该方法,获取用户对象
    def get_object(self):
        return self.request.user

"""
保存邮箱
请求路径: /users/emails
请求方式: PUT,认证
请求参数: email
返回值: email,id
"""
class UserEmailView(UpdateAPIView):
    serializer_class = UserEmailSerializer

    def get_object(self):
        return self.request.user


"""
校验邮件地址token
"""
class UserEmailCheckView(APIView):

    def get(self,request):
        #1,获取token,判断
        token = request.query_params.get("token")
        if not token:
            return Response({"message":"token丢失"},status=status.HTTP_400_BAD_REQUEST)

        #2,解密token,校验是否正确
        user = User.check_verify_url_token(token)

        if not user:
            return Response({"message":"用户不存在"},status=status.HTTP_400_BAD_REQUEST)

        #3,给用户邮箱激活
        user.email_active = True
        user.save()

        #4,返回响应
        return Response(status=status.HTTP_200_OK)

"""
新增地址

获取用户所有的地址
请求路径: /users/{user_id}/addresses
请求方式: GET
请求参数: 无,认证用户
返回值:adresses(列表),limit,default_address_id

请求路径: /users/{user_id}/addresses/{addresses_id}/status
请求方式: PUT
请求参数: 无,认证用户
返回值: default_address_id

"""
class UserAddressViewSet(CreateModelMixin,ListModelMixin,UpdateModelMixin,DestroyModelMixin,GenericViewSet):
    serializer_class = AddressSerializer

    # queryset = Address.objects.all() #表示所有用户的地址

    #给登陆的用户,获取的是未删除的地址
    def get_queryset(self):
        return self.request.user.addresses.filter(is_deleted=False)

    #0,重写create方法,系统提供的方法不能判断用户是否有20个地址了
    def create(self, request, *args, **kwargs):
        #1,获取用户地址数量,判断
        count = self.get_queryset().count()
        if count > 19:
            return Response({"message":"地址不能超过20个"})

        #2,调用父类方法创建即可
        return super().create(request,*args,**kwargs)

    #1,重写list方法,视图提供的序列化器的数据格式不符合需求
    def list(self, request, *args, **kwargs): # request == self.request
        # request.user # AnonyMouse
        #1,获取用户,用户收货地址
        user = request.user
        # addresses = user.addresses
        queryset = self.get_queryset()

        #2,获取序列化器
        serializer = self.get_serializer(queryset,many=True)

        #3,组织数据反回
        return Response({
            "addresses":serializer.data,
            "limit":20,
            "default_address_id":user.default_address.id if user.default_address else ""
        })

    #2,更新地址的状态(默认地址)
    @action(methods=["put"],detail=True)
    def status(self,request,pk):
        #1,获取用户,地址对象
        user = request.user
        address = self.get_object()

        #2,将地址设置给用户
        user.default_address = address
        user.save()

        #3,返回响应
        return Response({"message":"OK"})

    #3,修改用户地址
    @action(methods=["put"],detail=True)
    def title(self,request,pk):
        #1,获取地址, 获取数据
        address = self.get_object()
        dict_data = request.data

        #2,修改地址标题,入库
        # address.title = dict_data.get("title")
        # address.save()

        #3,使用序列化器实现
        serializer = AddressTitleSerializer(instance=address,data=dict_data)
        serializer.is_valid(raise_exception=True)
        serializer.save()

        #3,返回响应
        return Response({"title":serializer.data})

    #4,系统提供的方法是物理删除,重写成逻辑删除
    def destroy(self, request, *args, **kwargs):
        #1,获取地址
        address = self.get_object()

        #2,设置地址删除属性,保存
        address.is_deleted = True
        address.save()

        #3,响应
        return Response(status=status.HTTP_204_NO_CONTENT)


"""
1, 记录用户的浏览历史
    a,前端携带商品的id
    b,后端将商品id储存到redis中
2, 获取用户的浏览历史
    a,用户需要是登陆状态
    b,返回,id,name,price,defalut_image_url,comments
什么时候提供序列化器?
a, 需要转换数据的时候,校验数据的时候

什么时候需要提供数据集?
a, 查询,修改,删除,的时候
"""
from goods.serializers import HotSkuListSerializer
class UserBrowserHistoryView(CreateAPIView,ListAPIView):
    pagination_class = None

    #判断请求方式,使用的序列化器
    def get_serializer_class(self):
        if self.request.method == "POST":
            return UserBrowserHistorySerializer
        else:
            return HotSkuListSerializer

    # 判断请求方式,使用的序列化器
    def get_queryset(self):
        #1,获取reids中的所有浏览的商品编号
        redis_conn = get_redis_connection("history")
        skus_id = redis_conn.lrange("history_%s"%self.request.user.id,0,4)

        #2,根据商品编号查询,查询商品对象,添加到列表
        sku_list = []
        for sku_id in skus_id:
            sku = SKU.objects.get(id=sku_id)
            sku_list.append(sku)

        #3,返回数据
        return sku_list



#系统提供的认证方法,不能合并购物车,所以进行改写
class UserObtainJSONWebToken(ObtainJSONWebToken):

    def post(self, request, *args, **kwargs):
        #1,调用父类方法登陆认证
        response = super().post(request, *args, **kwargs)

        #2,获取序列化器
        serializer = self.get_serializer(data=request.data)

        #3,校验认证是否成功
        if serializer.is_valid():
            #3,1 获取user对象
            user = serializer.object.get('user') or request.user

            #3,2 调用方法,合并购物车数据
            response = merge_cookie_redis_cart(request,user,response)

        #4,返回
        return response